/***********************************************************************************************************************
 * ############################################# Application AdewebLite #############################################
 * AdewebLite Android est une application permettant de consulter des emplois du temps fournis par l'université UHP
 * avec ou sans connexion internet (informations gardées en mémoire à chaque synchronisation). Et utilisant la web
 * API ADE pour collecter les données.
 * @author Andrianjafintrimo Victor, Zanette Sébastien
 * 
 * Basée sur l'application du même nom, utilisant le flux RSS (données à traiter), de :
 * @author Schnell Michaël, Zanette Sébastien
 * **********************************************************************************************************************
 */

package ade.prime.analyzer;

import java.util.ArrayList;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Classe permettant de parser le flux XML récupérer grâce a la fonction
 * getEvent de l'API
 *
 * @author Zanette Sébastien, Andrianjafintrimo Victor
 */
public class ParserLesson extends DefaultHandler {

	@SuppressWarnings("unused")
	private static final String TAG = ParserLesson.class.getSimpleName() ;

	// nom des tags XML
	private static final String EVENT = "event"; //$NON-NLS-1$
	private static final String RESOURCES = "resources"; //$NON-NLS-1$
	private static final String RESOURCE = "resource"; //$NON-NLS-1$
	private static final String ADDITIONAL = "additional"; //$NON-NLS-1$
	private static final String ID = "id"; //$NON-NLS-1$
	private static final String NAME = "name"; //$NON-NLS-1$
	private static final String DATE = "date"; //$NON-NLS-1$
	private static final String STARTHOUR = "startHour"; //$NON-NLS-1$
	private static final String ENDHOUR = "endHour"; //$NON-NLS-1$
	private static final String CREATION = "creation"; //$NON-NLS-1$
	private static final String UPDATE = "lastUpdate"; //$NON-NLS-1$
	private static final String COLOR = "color"; //$NON-NLS-1$
	private static final String NOTE = "note"; //$NON-NLS-1$
	private static final String CATEGORY = "category"; //$NON-NLS-1$

	private static final String COLOR_VALUES_SEPARATOR = "," ; //$NON-NLS-1$
	private static final String COLOR_FORMAT = "#%02x%02x%02x" ; //$NON-NLS-1$

	// Array list de feeds	
	private ArrayList<FeedLesson> feeds;
	// Boolean permettant de savoir si nous sommes � l'int�rieur d'un EVENT
	private boolean inEvent;
	// Feed courant
	private FeedLesson currentFeed;
	private FeedResources currentResources;
	private FeedResource currentResource;
	// Buffer permettant de contenir les donn�es d'un tag XML
	private StringBuffer buffer;

	/**
	 * Appelle la fonction processingInstruction de la classe DefaultHandler
	 * @param target
	 * @param data
	 * @throws SAXException
	 */
	@Override
	public void processingInstruction(String target, String data) throws SAXException {
		super.processingInstruction(target, data);
	}

	/**
	 * Constructeur de la classe ParserLesson
	 */
	public ParserLesson() {
		super();
	}

	/**
	 * Cette méthode est appelée par le parser une et une seule fois au
	 * démarrage de l'analyse de votre flux xml. Elle est appelée avant toutes
	 * les autres méthodes de l'interface, à l'exception unique, évidemment, de
	 * la méthode setDocumentLocator. Cet évènement devrait vous permettre
	 * d'initialiser tout ce qui doit l'être avant le début du parcours du
	 * document.
	 *
	 * @throws SAXException
	 */
	@Override
	public void startDocument() throws SAXException {
		super.startDocument();
		this.feeds = new ArrayList<FeedLesson>();

	}

	/**
	 * Fonction �tant d�clench�e lorsque le parser trouve un tag XML C'est cette
	 * méthode que nous allons utiliser pour instancier un nouveau feed
	 *
	 * @param uri
	 * @param localName
	 * @param name
	 * @param attributes
	 * @throws SAXException
	 */
	@Override
	public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
		// Nous réinitialisons le buffer a chaque fois qu'il rencontre un EVENT
		this.buffer = new StringBuffer();

		// Ci dessous, localName contient le nom du tag rencontré

		// Nous avons rencontré un tag EVENT, il faut donc instancier un nouveau feed
		if (localName.equalsIgnoreCase(EVENT)) {
			this.currentFeed = new FeedLesson();
			this.currentFeed.setId(attributes.getValue(ID));
			this.currentFeed.setName(attributes.getValue(NAME));
			this.currentFeed.setEndHour(attributes.getValue(ENDHOUR));
			this.currentFeed.setStartHour(attributes.getValue(STARTHOUR));
			this.currentFeed.setDate(attributes.getValue(DATE));
			this.currentFeed.setCreation(attributes.getValue(CREATION));
			this.currentFeed.setUpdate(attributes.getValue(UPDATE));
			this.currentFeed.setColor(
					ParserLesson.parseColor(attributes.getValue(COLOR))) ;
			this.currentFeed.setNote(attributes.getValue(NOTE));
			this.inEvent = true;
		}


		// Vous pouvez d�finir des actions à effectuer pour chaque EVENT rencontré
		if (localName.equalsIgnoreCase(RESOURCES)) {
			this.currentResources = new FeedResources();
		}
		if (localName.equalsIgnoreCase(RESOURCE)) {
			this.currentResource = new FeedResource();
			this.currentResource.setId(attributes.getValue(ID));
			this.currentResource.setName(attributes.getValue(NAME));
			this.currentResource.setCategory(attributes.getValue(CATEGORY));
			this.currentResources.addResource(this.currentResource);
		}
		if (localName.equalsIgnoreCase(ADDITIONAL)) {
			// Nothing to do	
		}

	}

	/**
	 * Fonction étant déclenchée lorsque le parser a parsé l'intérieur de la
	 * balise XML La méthode characters a donc fait son ouvrage et tous les
	 * caractère inclus dans la balise en cours sont copiés dans le buffer On
	 * peut donc tranquillement les récupérer pour compléter notre objet
	 * currentFeed
	 *
	 * @param uri
	 * @param localName
	 * @param name
	 * @throws SAXException
	 */
	@Override
	public void endElement(String uri, String localName, String name) throws SAXException {

		if (localName.equalsIgnoreCase(RESOURCES)) {
			if (this.inEvent) {
				this.currentFeed.setResources(this.currentResources);
				this.buffer = null;
			}
		}

		if (localName.equalsIgnoreCase(RESOURCE)) {
			if (this.inEvent) {
				// Les caract�res sont dans l'objet buffer
				//this.currentFeed.setRessource(this.buffer.toString());				
				this.buffer = null;
			}
		}

		if (localName.equalsIgnoreCase(ADDITIONAL)) {
			if (this.inEvent) {
				//this.currentFeed.setAddictional(this.buffer.toString());				
				this.buffer = null;
			}
		}

		if (localName.equalsIgnoreCase(EVENT)) {
			//        	Log.d(TAG, ">> Lesson parsed !") ;
			this.feeds.add(this.currentFeed);
			this.inEvent = false;
		}
	}

	/**
	 *  * Tout ce qui est dans l'arborescence mais n'est pas partie int�grante
	 * d'un tag, d�clenche la lev�e de cet �v�nement. En g�n�ral, cet �v�nement
	 * est donc lev� tout simplement par la pr�sence de texte entre la balise
	 * d'ouverture et la balise de fermeture
	 * @param ch
	 * @param start
	 * @param length
	 */
	@Override
	public void characters(char[] ch, int start, int length) {
		String lecture = new String(ch, start, length);
		if (this.buffer != null) {
			this.buffer.append(lecture);
		}
	}

	/**
	 * Méthode permettant de récupérer l'instance de Feed courante
	 * @return 
	 */
	public ArrayList<FeedLesson> getData() {
		return this.feeds;

	}

	protected static String parseColor(String color) {
		String[] values = color.split(COLOR_VALUES_SEPARATOR) ;

		String result = String.format(COLOR_FORMAT, 
				Integer.valueOf(values[0]), 
				Integer.valueOf(values[1]), 
				Integer.valueOf(values[2])) ;

		//    	Log.d("ParserLesson", String.format( //$NON-NLS-1$
		//    			"[parseColor] Source: '%s', Result: '%s'", //$NON-NLS-1$
		//    			color, result)) ;

		return result ;
	}// parseColor(String)
}
